home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''Provides an Orca speech server for Speech Dispatcher backend.
-
- NOTE: THIS IS EXPERIMENTAL ONLY AND IS NOT A SUPPORTED COMPONENT OF ORCA.
- '''
- __id__ = '$Id: speechdispatcherfactory.py 4659 2009-03-30 17:37:48Z wwalker $'
- __version__ = '$Revision: 4659 $'
- __date__ = '$Date: 2009-03-30 13:37:48 -0400 (Mon, 30 Mar 2009) $'
- __author__ = 'Tomas Cerha <cerha@brailcom.org>'
- __copyright__ = 'Copyright (c) 2006-2008 Brailcom, o.p.s.'
- __license__ = 'LGPL'
- import gobject
- import debug
- import speechserver
- import settings
- import orca
- from acss import ACSS
- from orca_i18n import _
-
- try:
- import speechd
- except:
- _speechd_available = False
-
- _speechd_available = True
-
- try:
- getattr(speechd, 'CallbackType')
- except AttributeError:
- _speechd_version_ok = False
-
- _speechd_version_ok = True
-
- class SpeechServer(speechserver.SpeechServer):
- _active_servers = { }
- DEFAULT_SERVER_ID = 'default'
- _SERVER_NAMES = {
- DEFAULT_SERVER_ID: _('Default Synthesizer') }
- KEY_NAMES = {
- '_': 'underscore',
- 'space': 'space',
- '"': 'double-quote' }
-
- def getFactoryName():
- return _('Speech Dispatcher')
-
- getFactoryName = staticmethod(getFactoryName)
-
- def getSpeechServers():
- servers = []
- default = SpeechServer._getSpeechServer(SpeechServer.DEFAULT_SERVER_ID)
- if default is not None:
- servers.append(default)
- for module in default.list_output_modules():
- servers.append(SpeechServer._getSpeechServer(module))
-
-
- return servers
-
- getSpeechServers = staticmethod(getSpeechServers)
-
- def _getSpeechServer(cls, serverId):
- """Return an active server for given id.
-
- Attempt to create the server if it doesn't exist yet. Returns None
- when it is not possible to create the server.
-
- """
- if serverId not in cls._active_servers:
- cls(serverId)
-
- return cls._active_servers.get(serverId)
-
- _getSpeechServer = classmethod(_getSpeechServer)
-
- def getSpeechServer(info = None):
- if info is not None:
- thisId = info[1]
- else:
- thisId = SpeechServer.DEFAULT_SERVER_ID
- return SpeechServer._getSpeechServer(thisId)
-
- getSpeechServer = staticmethod(getSpeechServer)
-
- def shutdownActiveServers():
- for server in SpeechServer._active_servers.values():
- server.shutdown()
-
-
- shutdownActiveServers = staticmethod(shutdownActiveServers)
-
- def __init__(self, serverId):
- super(SpeechServer, self).__init__()
- self._id = serverId
- self._client = None
- self._current_voice_properties = { }
- self._acss_manipulators = ((ACSS.RATE, self._set_rate), (ACSS.AVERAGE_PITCH, self._set_pitch), (ACSS.GAIN, self._set_volume), (ACSS.FAMILY, self._set_family))
- if not _speechd_available:
- debug.println(debug.LEVEL_WARNING, 'Speech Dispatcher interface not installed.')
- return None
- if not _speechd_version_ok:
- debug.println(debug.LEVEL_WARNING, 'Speech Dispatcher version 0.6.2 or later is required.')
- return None
- self._PUNCTUATION_MODE_MAP = {
- settings.PUNCTUATION_STYLE_ALL: speechd.PunctuationMode.ALL,
- settings.PUNCTUATION_STYLE_MOST: speechd.PunctuationMode.SOME,
- settings.PUNCTUATION_STYLE_SOME: speechd.PunctuationMode.SOME,
- settings.PUNCTUATION_STYLE_NONE: speechd.PunctuationMode.NONE }
- self._CALLBACK_TYPE_MAP = {
- speechd.CallbackType.BEGIN: speechserver.SayAllContext.PROGRESS,
- speechd.CallbackType.CANCEL: speechserver.SayAllContext.INTERRUPTED,
- speechd.CallbackType.END: speechserver.SayAllContext.COMPLETED }
- self._default_voice_name = _('%s default voice') % serverId
-
- try:
- self._init()
- except:
- _speechd_version_ok
- _speechd_available
- debug.println(debug.LEVEL_WARNING, 'Speech Dispatcher service failed to connect:')
- debug.printException(debug.LEVEL_WARNING)
-
- SpeechServer._active_servers[serverId] = self
-
-
- def _init(self):
- self._client = client = speechd.SSIPClient('Orca', component = self._id)
- if self._id != self.DEFAULT_SERVER_ID:
- client.set_output_module(self._id)
-
- self._current_voice_properties = { }
- mode = self._PUNCTUATION_MODE_MAP[settings.verbalizePunctuationStyle]
- client.set_punctuation(mode)
-
-
- def _send_command(self, command, *args, **kwargs):
- if hasattr(speechd, 'SSIPCommunicationError'):
-
- try:
- return command(*args, **kwargs)
- except speechd.SSIPCommunicationError:
- debug.println(debug.LEVEL_CONFIGURATION, 'Speech Dispatcher connection lost. Trying to reconnect.')
- self.reset()
- return command(*args, **kwargs)
-
-
- None<EXCEPTION MATCH>speechd.SSIPCommunicationError
- return command(*args, **kwargs)
-
-
- def _set_rate(self, acss_rate):
- rate = int(2 * max(0, min(99, acss_rate)) - 98)
- self._send_command(self._client.set_rate, rate)
-
-
- def _set_pitch(self, acss_pitch):
- pitch = int(20 * max(0, min(9, acss_pitch)) - 90)
- self._send_command(self._client.set_pitch, pitch)
-
-
- def _set_volume(self, acss_volume):
- volume = int(15 * max(0, min(9, acss_volume)) - 35)
- self._send_command(self._client.set_volume, volume)
-
-
- def _set_family(self, acss_family):
- locale = acss_family[speechserver.VoiceFamily.LOCALE]
- if locale:
- lang = locale.split('_')[0]
- if lang and len(lang) == 2:
- self._send_command(self._client.set_language, lang)
-
-
-
- try:
- set_synthesis_voice = self._client.set_synthesis_voice
- except AttributeError:
- pass
-
- name = acss_family[speechserver.VoiceFamily.NAME]
- if name != self._default_voice_name:
- self._send_command(set_synthesis_voice, name)
-
-
-
- def _apply_acss(self, acss):
- if acss is None:
- acss = settings.voices[settings.DEFAULT_VOICE]
-
- current = self._current_voice_properties
- for acss_property, method in self._acss_manipulators:
- value = acss.get(acss_property)
- if value is not None and current.get(acss_property) != value:
- method(value)
- current[acss_property] = value
- continue
-
-
-
- def _speak(self, text, acss, **kwargs):
- self._apply_acss(acss)
- self._send_command(self._client.speak, text, **kwargs)
-
-
- def _say_all(self, iterator, orca_callback):
- '''Process another sayAll chunk.
-
- Called by the gidle thread.
-
- '''
-
- try:
- (context, acss) = iterator.next()
- except StopIteration:
- pass
-
-
- def callback(callbackType, index_mark = (None, None, None, None)):
- t = self._CALLBACK_TYPE_MAP[callbackType]
- if t == speechserver.SayAllContext.PROGRESS:
- if index_mark:
- context.currentOffset = int(index_mark)
- else:
- context.currentOffset = context.startOffset
- elif t == speechserver.SayAllContext.COMPLETED:
- context.currentOffset = context.endOffset
-
- gobject.idle_add(orca_callback, context, t)
- if t == speechserver.SayAllContext.COMPLETED:
- gobject.idle_add(self._say_all, iterator, orca_callback)
-
-
- self._speak(context.utterance, acss, callback = callback, event_types = self._CALLBACK_TYPE_MAP.keys())
- return False
-
-
- def _cancel(self):
- self._send_command(self._client.cancel)
-
-
- def _change_default_speech_rate(self, decrease = False):
- acss = settings.voices[settings.DEFAULT_VOICE]
- if not decrease or -1:
- pass
- delta = settings.speechRateDelta * +1
- rate = acss[ACSS.RATE]
- acss[ACSS.RATE] = max(0, min(99, rate + delta))
- debug.println(debug.LEVEL_CONFIGURATION, 'Speech rate is now %d' % rate)
- if not decrease or _('slower.'):
- pass
- self.speak(_('faster.'), acss = acss)
-
-
- def _change_default_speech_pitch(self, decrease = False):
- acss = settings.voices[settings.DEFAULT_VOICE]
- if not decrease or -1:
- pass
- delta = settings.speechPitchDelta * +1
- pitch = acss[ACSS.AVERAGE_PITCH]
- acss[ACSS.AVERAGE_PITCH] = max(0, min(9, pitch + delta))
- debug.println(debug.LEVEL_CONFIGURATION, 'Speech pitch is now %d' % pitch)
- if not decrease or _('lower.'):
- pass
- self.speak(_('higher.'), acss = acss)
-
-
- def getInfo(self):
- return [
- self._SERVER_NAMES.get(self._id, self._id),
- self._id]
-
-
- def getVoiceFamilies(self):
- getlocale = getlocale
- LC_MESSAGES = LC_MESSAGES
- import locale
- locale = getlocale(LC_MESSAGES)[0]
- if locale is None or locale == 'C':
- lang = None
- else:
- lang = locale.split('_')[0]
- voices = ((self._default_voice_name, lang, None),)
-
- try:
- list_synthesis_voices = self._client.list_synthesis_voices
- except AttributeError:
- pass
-
- voices += self._send_command(list_synthesis_voices)
- families = [ speechserver.VoiceFamily({
- speechserver.VoiceFamily.NAME: name,
- speechserver.VoiceFamily.LOCALE: lang }) for name, lang, dialect in voices ]
- return families
-
-
- def speak(self, text = None, acss = None, interrupt = True):
- if text:
- self._speak(text, acss)
-
-
-
- def queueText(self, text = '', acss = None):
- if text:
- self._speak(text, acss)
-
-
-
- def speakUtterances(self, utteranceList, acss = None, interrupt = True):
- for utterance in utteranceList:
- if utterance:
- self._speak(utterance, acss)
- continue
-
-
-
- def sayAll(self, utteranceIterator, progressCallback):
- gobject.idle_add(self._say_all, utteranceIterator, progressCallback)
-
-
- def speakCharacter(self, character, acss = None):
- self._apply_acss(acss)
- if character == '\n':
- self._send_command(self._client.sound_icon, 'end-of-line')
- else:
- self._send_command(self._client.char, character)
-
-
- def speakKeyEvent(self, event_string, eventType):
- if eventType == orca.KeyEventType.PRINTABLE:
- if event_string.decode('UTF-8').isupper():
- acss = settings.voices[settings.UPPERCASE_VOICE]
- else:
- acss = None
- key = self.KEY_NAMES.get(event_string, event_string)
- self._apply_acss(acss)
- self._send_command(self._client.key, key)
- else:
- return super(SpeechServer, self).speakKeyEvent(event_string, eventType)
- return eventType == orca.KeyEventType.PRINTABLE
-
-
- def increaseSpeechRate(self, step = 5):
- self._change_default_speech_rate()
-
-
- def decreaseSpeechRate(self, step = 5):
- self._change_default_speech_rate(decrease = True)
-
-
- def increaseSpeechPitch(self, step = 0.5):
- self._change_default_speech_pitch()
-
-
- def decreaseSpeechPitch(self, step = 0.5):
- self._change_default_speech_pitch(decrease = True)
-
-
- def stop(self):
- self._cancel()
-
-
- def shutdown(self):
- self._client.close()
- del SpeechServer._active_servers[self._id]
-
-
- def reset(self, text = None, acss = None):
- self._client.close()
- self._init()
-
-
- def list_output_modules(self):
- '''Return names of available output modules as a tuple of strings.
-
- This method is not a part of Orca speech API, but is used internally
- by the Speech Dispatcher backend.
-
- The returned tuple can be empty if the information can not be
- obtained (e.g. with an older Speech Dispatcher version).
-
- '''
-
- try:
- return self._send_command(self._client.list_output_modules)
- except AttributeError:
- return ()
- except speechd.SSIPCommandError:
- return ()
- else:
- return None
-
-
-
-